home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 21 / emacsrc / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-14  |  12.4 KB  |  366 lines

  1. /*
  2.  * This program is in public domain; written by Dave G. Conroy.
  3.  * This file contains the main driving routine, and some keyboard processing
  4.  * code, for the MicroEMACS screen editor.
  5.  *
  6.  * REVISION HISTORY:
  7.  *
  8.  * 1.0  Steve Wilhite, 30-Nov-85
  9.  *      - Removed the old LK201 and VT100 logic. Added code to support the
  10.  *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
  11.  *        1 Console In ROM INT. See "rainbow.h" for the function key definitions.
  12.  *
  13.  * 2.0  George Jones, 12-Dec-85      - Ported to Amiga.
  14.  * 3.0  prabhaker mateti, 3-Jan-86, ported to Atari 520ST
  15.  */
  16. /*    #include        <stdio.h>    */
  17. #include        "ed.h"
  18. #include    "osbind.h"
  19.  
  20. #include    "keynames.h"
  21.  
  22. #define GOOD    0
  23.  
  24. extern    KEYBIND    keybind[];
  25. extern    int    nkeybind;
  26. extern    char    msginit[];
  27.  
  28. int     currow;                         /* Working cursor row           */
  29. int     curcol;                         /* Working cursor column        */
  30. int     fillcol;                        /* Current fill column          */
  31. int     thisflag;                       /* Flags, this command          */
  32. int     lastflag;                       /* Flags, last command          */
  33. int     curgoal;                        /* Goal column                  */
  34. BUFFER  *curbp;                         /* Current buffer               */
  35. WINDOW  *curwp;                         /* Current window               */
  36. BUFFER  *bheadp;                        /* BUFFER listhead              */
  37. WINDOW  *wheadp;                        /* WINDOW listhead              */
  38. BUFFER  *blistp;                        /* Buffer list BUFFER           */
  39. short   kbdm[NKBDM] = {CTLX|')'};       /* Macro                        */
  40. short   *kbdmip;                        /* Input  for above             */
  41. short   *kbdmop;                        /* Output for above             */
  42. char    pat[NPAT];                      /* Pattern                      */
  43.  
  44. main(argc, argv)
  45. char    *argv[];
  46. {
  47.         register int    c;
  48.         register int    f;
  49.         register int    n;
  50.         register int    mflag;
  51.         char            bname[NBUFN];
  52.  
  53.         strcpy(bname, "main");                  /* Work out the name of */
  54.         if (argc > 1)                           /* the default buffer.  */
  55.                 makename(bname, argv[1]);
  56.         edinit(bname);                          /* Buffers, windows.    */
  57.         vtinit();                               /* Displays.            */
  58.         update();                               /* You have to update   */
  59.     mlwrite(msginit);
  60.         if (argc > 1) {
  61.                 readin(argv[1]);                /* in case "[New file]" */
  62.         }
  63.         lastflag = 0;                           /* Fake last flags.     */
  64. loop:
  65.         update();                               /* Fix up the screen    */
  66.         c = getkey();
  67.         if (mpresf != FALSE) {
  68.                 mlerase();
  69.                 update();
  70.                 if (c == ' ')                   /* ITS EMACS does this  */
  71.                         goto loop;
  72.         }
  73.         f = FALSE;
  74.         n = 1;
  75.         if (c == (CTRL|'U')) {                  /* ^U, start argument   */
  76.                 f = TRUE;
  77.                 n = 4;                          /* with argument of 4 */
  78.                 mflag = 0;                      /* that can be discarded. */
  79.                 mlwrite("Arg: 4");
  80.                 while ((c=getkey()) >='0' && c<='9' || c==(CTRL|'U') || c=='-'){
  81.                         if (c == (CTRL|'U'))
  82.                                 n = n*4;
  83.                         /*
  84.                          * If dash, and start of argument string, set arg.
  85.                          * to -1.  Otherwise, insert it.
  86.                          */
  87.                         else if (c == '-') {
  88.                                 if (mflag)
  89.                                         break;
  90.                                 n = 0;
  91.                                 mflag = -1;
  92.                         }
  93.                         /*
  94.                          * If first digit entered, replace previous argument
  95.                          * with digit and set sign.  Otherwise, append to arg.
  96.                          */
  97.                         else {
  98.                                 if (!mflag) {
  99.                                         n = 0;
  100.                                         mflag = 1;
  101.                                 }
  102.                                 n = 10*n + c - '0';
  103.                         }
  104.                         mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1));
  105.                 }
  106.                 /*
  107.                  * Make arguments preceded by a minus sign negative and change
  108.                  * the special argument "^U -" to an effective "^U -1".
  109.                  */
  110.                 if (mflag == -1) {
  111.                         if (n == 0)
  112.                                 n++;
  113.                         n = -n;
  114.                 }
  115.         }
  116.         if (c == (CTRL|'X'))                    /* ^X is a prefix       */
  117.                 c = CTLX | getctl();
  118.         if (kbdmip != NULL) {                   /* Save macro strokes.  */
  119.                 if (c!=(CTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
  120.                         ctrlg(FALSE, 0);
  121.                         goto loop;
  122.                 }
  123.                 if (f != FALSE) {
  124.                         *kbdmip++ = (CTRL|'U');
  125.                         *kbdmip++ = n;
  126.                 }
  127.                 *kbdmip++ = c;
  128.         }
  129.         execute(c, f, n);                       /* Do it.               */
  130.         goto loop;
  131. }
  132.  
  133. /*
  134.  * Initialize all of the buffers and windows. The buffer name is passed down
  135.  * as an argument, because the main routine may have been told to read in a
  136.  * file by default, and we want the buffer name to be right.
  137.  */
  138. edinit(bname)
  139. char    bname[];
  140. {
  141.         register BUFFER *bp;
  142.         register WINDOW *wp;
  143.  
  144.     keysetup();                /* setup keymap of ST    */
  145.         bp = bfind(bname, TRUE, 0);             /* First buffer         */
  146.         blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer   */
  147.         wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window         */
  148.         if (bp==NULL || wp==NULL || blistp==NULL)
  149.                 exit(1);
  150.         curbp  = bp;                            /* Make this current    */
  151.         wheadp = wp;
  152.         curwp  = wp;
  153.         wp->w_wndp  = NULL;                     /* Initialize window    */
  154.         wp->w_bufp  = bp;
  155.         bp->b_nwnd  = 1;                        /* Displayed.           */
  156.         wp->w_linep = bp->b_linep;
  157.         wp->w_dotp  = bp->b_linep;
  158.         wp->w_doto  = 0;
  159.         wp->w_markp = NULL;
  160.         wp->w_marko = 0;
  161.         wp->w_toprow = 0;
  162.         wp->w_ntrows = term.t_nrow-1;           /* "-1" for mode line.  */
  163.         wp->w_force = 0;
  164.         wp->w_flag  = WFMODE|WFHARD;            /* Full.                */
  165. }
  166.         
  167. /*
  168.  * This is the general command execution routine. It handles the fake binding
  169.  * of all the keys to "self-insert". It also clears out the "thisflag" word,
  170.  * and arranges to move it to the "lastflag", so that the next command can
  171.  * look at it. Return the status of command.
  172.  */
  173. execute(c, f, n)
  174. register int    c;
  175. int        f, n;
  176. {
  177.         register KEYBIND *ktp, *ktp2;
  178.         register int    status;
  179.  
  180.     ktp2 =  &keybind[nkeybind];              /* Look in key table.   */
  181.     for (ktp = &keybind[0]; ktp < ktp2; ktp++) {
  182.                 if (ktp->k_code == c) {
  183.                         thisflag = 0;
  184.                         status   = (*ktp->k_fp)(f, n);
  185.                         lastflag = thisflag;
  186.                         return (status);
  187.                 }
  188.         }
  189.  
  190.         /*
  191.          * If a space was typed, fill column is defined, the argument is non-
  192.          * negative, and we are now past fill column, perform word wrap.
  193.          */
  194. /*    bug!!!
  195. **        if (c == ' ' && fillcol > 0 && n>=0 && getccol(FALSE) > fillcol)
  196. **                wrapword();
  197. **
  198. */
  199.  
  200.         if ((c>=0x20 && c<=0x7E)                /* Self inserting.      */
  201.         ||  (c>=0xA0 && c<=0xFE)) {        /* these too are ok on ST */
  202.                 if (n <= 0) {                   /* Fenceposts.          */
  203.                         lastflag = 0;
  204.                         return (n<0 ? FALSE : TRUE);
  205.                 }
  206.                 thisflag = 0;                   /* For the future.      */
  207.                 status   = linsert(n, c);
  208.                 lastflag = thisflag;
  209.                 return (status);
  210.         }
  211.         lastflag = 0;                           /* Fake last flags.     */
  212.         return (FALSE);
  213. }
  214.  
  215. /*
  216.  * Read in a key.
  217.  * Do the standard keyboard preprocessing. Convert the keys to the internal
  218.  * character set.
  219.  */
  220. getkey()
  221. {
  222.         register int    c;
  223.  
  224.         c = Crawcin();
  225.  
  226.         if (c == METACH) {                      /* Apply M- prefix      */
  227.                 c = getctl();
  228.                 return (META | c);
  229.         }
  230.  
  231.         if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
  232.                 c = CTRL | (c+'@');
  233.         return (c);
  234. }
  235.  
  236. /*
  237.  * Get a key.
  238.  * Apply control modifications to the read key.
  239.  */
  240. getctl()
  241. {
  242.         register int    c;
  243.  
  244.         c = Crawcin();
  245.         if (c>='a' && c<='z')                   /* Force to upper       */
  246.                 c -= 0x20;
  247.         if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
  248.                 c = CTRL | (c+'@');
  249.         return (c);
  250. }
  251.  
  252. /*
  253.  * Fancy quit command, as implemented by Norm. If the current buffer has
  254.  * changed do a write current buffer and exit emacs, otherwise simply exit.
  255.  */
  256. quickexit(f, n)
  257. {
  258.         if ((curbp->b_flag&BFCHG) != 0          /* Changed.             */
  259.         && (curbp->b_flag&BFTEMP) == 0)         /* Real.                */
  260.                 filesave(f, n);
  261.         quit(f, n);                             /* conditionally quit   */
  262. }
  263.  
  264. /*
  265.  * Quit command. If an argument, always quit. Otherwise confirm if a buffer
  266.  * has been changed and not written out. Normally bound to "C-X C-C".
  267.  */
  268. quit(f, n)
  269. {
  270.         register int    s;
  271.  
  272.         if ((f != FALSE) || (anycb() == FALSE))    goto doquit;
  273.     listbuffers(FALSE, 1);
  274.     update();
  275.     s = mlyesno("Unsaved buffers exist! Quit");
  276.            if (s != TRUE) return (s);
  277.  
  278.     doquit:
  279.                 vttidy();
  280.         keyreset();        /* reset ST keys    */
  281.                    exit(GOOD);
  282. }
  283.  
  284. /*
  285.  * Begin a keyboard macro.
  286.  * Error if not at the top level in keyboard processing. Set up variables and
  287.  * return.
  288.  */
  289. ctlxlp(f, n)
  290. {
  291.         if (kbdmip!=NULL || kbdmop!=NULL) {
  292.                 mlwrite("Not now");
  293.                 return (FALSE);
  294.         }
  295.         mlwrite("[Start macro]");
  296.         kbdmip = &kbdm[0];
  297.         return (TRUE);
  298. }
  299.  
  300. /*
  301.  * End keyboard macro. Check for the same limit conditions as the above
  302.  * routine. Set up the variables and return to the caller.
  303.  */
  304. ctlxrp(f, n)
  305. {
  306.         if (kbdmip == NULL) {
  307.                 mlwrite("Not now");
  308.                 return (FALSE);
  309.         }
  310.         mlwrite("[End macro]");
  311.         kbdmip = NULL;
  312.         return (TRUE);
  313. }
  314.  
  315. /*
  316.  * Execute a macro.
  317.  * The command argument is the number of times to loop. Quit as soon as a
  318.  * command gets an error. Return TRUE if all ok, else FALSE.
  319.  */
  320. ctlxe(f, n)
  321. {
  322.         register int    c;
  323.         register int    af;
  324.         register int    an;
  325.         register int    s;
  326.  
  327.         if (kbdmip!=NULL || kbdmop!=NULL) {
  328.                 mlwrite("Not now");
  329.                 return (FALSE);
  330.         }
  331.         if (n <= 0) 
  332.                 return (TRUE);
  333.         do {
  334.                 kbdmop = &kbdm[0];
  335.                 do {
  336.                         af = FALSE;
  337.                         an = 1;
  338.                         if ((c = *kbdmop++) == (CTRL|'U')) {
  339.                                 af = TRUE;
  340.                                 an = *kbdmop++;
  341.                                 c  = *kbdmop++;
  342.                         }
  343.                         s = TRUE;
  344.                 } while (c!=(CTLX|')') && (s=execute(c, af, an))==TRUE);
  345.                 kbdmop = NULL;
  346.         } while (s==TRUE && --n);
  347.         return (s);
  348. }
  349.  
  350. /*
  351.  * Abort.
  352.  * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
  353.  * Sometimes called as a routine, to do general aborting of stuff.
  354.  */
  355. ctrlg(f, n)
  356. {
  357.     mlwrite("^G...ok!");
  358.         if (kbdmip != NULL) {
  359.                 kbdm[0] = (CTLX|')');
  360.                 kbdmip  = NULL;
  361.         }
  362.         return (ABORT);
  363. }
  364.  
  365. /* -eof- */
  366.